{ "metadata": { "name": "", "signature": "sha256:cca24d21958b8882ea9199cf6047088a5e1fbb1faceae8058e342ea559fea1cb" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "code", "collapsed": false, "input": [ "import plotly.plotly as py\n", "from plotly.graph_objs import *" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stderr", "text": [ "/Users/chris/anaconda/lib/python2.7/site-packages/pandas/computation/expressions.py:21: UserWarning: The installed version of numexpr 2.0.1 is not supported in pandas and will be not be used\n", "The minimum supported version is 2.1\n", "\n", " \"version is 2.1\\n\".format(ver=ver), UserWarning)\n" ] } ], "prompt_number": 1 }, { "cell_type": "code", "collapsed": false, "input": [ "from plotly.widgets import GraphWidget" ], "language": "python", "metadata": {}, "outputs": [ { "javascript": [ "window.genUID = function() {\n", " return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n", " var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);\n", " return v.toString(16);\n", " });\n", "};\n", "\n", "require([\"widgets/js/widget\"], function(WidgetManager){\n", "\n", " var GraphView = IPython.DOMWidgetView.extend({\n", " render: function(){\n", "\n", " console.log('render!');\n", "\n", " var that = this;\n", "\n", " var graphId = window.genUID();\n", " var loadingId = 'loading-'+graphId;\n", "\n", "\n", " var _graph_url = that.model.get('_graph_url');\n", "\n", " // variable plotlyDomain in the case of enterprise\n", " var url_parts = _graph_url.split('/');\n", " var plotlyDomain = url_parts[0] + '//' + url_parts[2];\n", "\n", " if(!('plotlyDomains' in window)){\n", " window.plotlyDomains = {};\n", " }\n", " window.plotlyDomains[graphId] = plotlyDomain;\n", "\n", " // Place IFrame in output cell div `$el`\n", " that.$el.css('width', '100%');\n", " that.$graph = $([''].join(' '));\n", " that.$graph.appendTo(that.$el);\n", "\n", " that.$loading = $('
Initializing...
')\n", " .appendTo(that.$el);\n", "\n", " // initialize communication with the iframe\n", " if(!('pingers' in window)){\n", " window.pingers = {};\n", " }\n", "\n", " window.pingers[graphId] = setInterval(function() {\n", " that.graphContentWindow = $('#'+graphId)[0].contentWindow;\n", " console.log('posting ping: ', plotlyDomain);\n", " that.graphContentWindow.postMessage({task: 'ping'}, plotlyDomain);\n", " }, 200);\n", "\n", " // Assign a message listener to the 'message' events\n", " // from iframe's postMessage protocol.\n", " // Filter the messages by iframe src so that the right message\n", " // gets passed to the right widget\n", " if(!('messageListeners' in window)){\n", " window.messageListeners = {};\n", " }\n", "\n", " window.messageListeners[graphId] = function(e) {\n", " console.log('message: ', e.data);\n", " if(_graph_url.indexOf(e.origin)>-1) {\n", " var frame = document.getElementById(graphId);\n", "\n", " if(frame === null){\n", " // frame doesn't exist in the dom anymore, clean up it's old event listener\n", " window.removeEventListener('message', window.messageListeners[graphId]);\n", " clearInterval(window.pingers[graphId]);\n", " } else if(frame.contentWindow === e.source) {\n", " // TODO: Stop event propagation, so each frame doesn't listen and filter\n", " var frameContentWindow = $('#'+graphId)[0].contentWindow;\n", " var message = e.data;\n", "\n", " if('pong' in message && message.pong) {\n", " $('#loading-'+graphId).hide();\n", " clearInterval(window.pingers[graphId]);\n", " that.send({event: 'pong', graphId: graphId});\n", " } else if (message.type==='hover' ||\n", " message.type==='zoom' ||\n", " message.type==='click' ||\n", " message.type==='unhover') {\n", "\n", " // click and hover events contain all of the data in the traces,\n", " // which can be a very large object and may take a ton of time\n", " // to pass to the python backend. Strip out the data, and require\n", " // the user to call get_figure if they need trace information\n", " if(message.type !== 'zoom') {\n", " for(var i in message.points) {\n", " delete message.points[i].data;\n", " }\n", " }\n", " that.send({event: message.type, message: message, graphId: graphId});\n", " }\n", " }\n", " }\n", " };\n", "\n", " window.removeEventListener('message', window.messageListeners[graphId]);\n", " window.addEventListener('message', window.messageListeners[graphId]);\n", "\n", " },\n", "\n", " update: function() {\n", " // Listen for messages from the graph widget in python\n", " var jmessage = this.model.get('_message');\n", " var message = JSON.parse(jmessage);\n", "\n", " // check for duplicate messages\n", " if(!('messageIds' in window)){\n", " window.messageIds = {};\n", " }\n", "\n", " if(!(message.uid in window.messageIds)){\n", " // message hasn't been received yet, do stuff\n", " window.messageIds[message.uid] = true;\n", "\n", " var plot = $('#'+message.graphId)[0].contentWindow;\n", " plot.postMessage(message, window.plotlyDomains[message.graphId]);\n", " }\n", "\n", " return GraphView.__super__.update.apply(this);\n", " }\n", " });\n", "\n", " // Register the GraphView with the widget manager.\n", " WidgetManager.register_widget_view('GraphView', GraphView);\n", "});\n", "\n", "//@ sourceURL=graphWidget.js\n" ], "metadata": {}, "output_type": "display_data", "text": [ "" ] } ], "prompt_number": 2 }, { "cell_type": "code", "collapsed": false, "input": [ "help(GraphWidget)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Help on class GraphWidget in module plotly.widgets.graph_widget:\n", "\n", "class GraphWidget(IPython.html.widgets.widget.DOMWidget)\n", " | An interactive Plotly graph widget for use in IPython\n", " | Notebooks.\n", " | \n", " | Method resolution order:\n", " | GraphWidget\n", " | IPython.html.widgets.widget.DOMWidget\n", " | IPython.html.widgets.widget.Widget\n", " | IPython.config.configurable.LoggingConfigurable\n", " | IPython.config.configurable.Configurable\n", " | IPython.utils.traitlets.HasTraits\n", " | IPython.utils.traitlets._NewBase\n", " | __builtin__.object\n", " | \n", " | Methods defined here:\n", " | \n", " | __init__(self, graph_url='https://plot.ly/~playground/7', **kwargs)\n", " | Initialize a plotly graph widget\n", " | \n", " | Args:\n", " | graph_url: The url of a Plotly graph\n", " | \n", " | Example:\n", " | ```\n", " | GraphWidget('https://plot.ly/~chris/3375')\n", " | ```\n", " | \n", " | add_traces(self, traces, new_indices=None)\n", " | Add new data traces to a graph.\n", " | \n", " | If `new_indices` isn't specified, they are simply appended.\n", " | \n", " | Args:\n", " | traces (dict or list of dicts, or class of plotly.graph_objs):trace\n", " | new_indices (list[int]|None), optional: The final indices the\n", " | added traces should occupy in the graph.\n", " | \n", " | Examples:\n", " | Initialization - Start each example below with this setup:\n", " | ```\n", " | from plotly.widgets import Graph\n", " | from plotly.graph_objs import Scatter\n", " | from IPython.display import display\n", " | \n", " | graph = GraphWidget('https://plot.ly/~chris/3979')\n", " | display(graph)\n", " | ```\n", " | \n", " | Example 1 - Add a scatter/line trace to the graph\n", " | ```\n", " | graph.add_traces(Scatter(x = [1, 2, 3], y = [5, 4, 5]))\n", " | ```\n", " | \n", " | Example 2 - Add a scatter trace and set it to to be the\n", " | second trace. This will appear as the second\n", " | item in the legend.\n", " | ```\n", " | graph.add_traces(Scatter(x = [1, 2, 3], y = [5, 6, 5]),\n", " | new_indices=[1])\n", " | ```\n", " | \n", " | Example 3 - Add multiple traces to the graph\n", " | ```\n", " | graph.add_traces([\n", " | Scatter(x = [1, 2, 3], y = [5, 6, 5]),\n", " | Scatter(x = [1, 2.5, 3], y = [5, 8, 5])\n", " | ])\n", " | ```\n", " | \n", " | delete_traces(self, indices)\n", " | Delete data traces from a graph.\n", " | \n", " | Args:\n", " | indices (list[int]): The indices of the traces to be removed\n", " | \n", " | Example - Delete the 2nd trace:\n", " | ```\n", " | from plotly.widgets import Graph\n", " | from IPython.display import display\n", " | \n", " | graph = GraphWidget('https://plot.ly/~chris/3979')\n", " | display(graph)\n", " | \n", " | \n", " | graph.delete_traces([1])\n", " | ```\n", " | \n", " | hover(self, *hover_objs)\n", " | Show hover labels over the points specified in hover_obj.\n", " | \n", " | Hover labels are the labels that normally appear when the\n", " | mouse hovers over points in the plotly graph.\n", " | \n", " | Args:\n", " | hover_objs (tuple of dicts):\n", " | Specifies which points to place hover labels over.\n", " | \n", " | The location of the hover labels is described by a dict with\n", " | keys and'xval' and/or 'yval' or 'curveNumber' and 'pointNumber'\n", " | and optional keys 'hovermode' and 'subplot'\n", " | \n", " | 'xval' and 'yval' specify the (x, y) coordinates to\n", " | place the label.\n", " | 'xval' and 'yval need to be close to a point drawn in a graph.\n", " | \n", " | 'curveNumber' and 'pointNumber' specify the trace number and\n", " | the index theof the point in that trace respectively.\n", " | \n", " | 'subplot' describes which axes to the coordinates refer to.\n", " | By default, it is equal to 'xy'. For example, to specify the\n", " | second x-axis and the third y-axis, set 'subplot' to 'x2y3'\n", " | \n", " | 'hovermode' is either 'closest', 'x', or 'y'.\n", " | When set to 'x', all data sharing the same 'x' coordinate will\n", " | be shown on screen with corresponding trace labels.\n", " | When set to 'y' all data sharing the same 'y' coordinates will\n", " | be shown on the screen with corresponding trace labels.\n", " | When set to 'closest', information about the data point closest\n", " | to where the viewer is hovering will appear.\n", " | \n", " | Note: If 'hovermode' is 'x', only 'xval' needs to be set.\n", " | If 'hovermode' is 'y', only 'yval' needs to be set.\n", " | If 'hovermode' is 'closest', 'xval' and 'yval' both\n", " | need to be set.\n", " | \n", " | Note: 'hovermode' can be toggled by the user in the graph\n", " | toolbar.\n", " | \n", " | Note: It is not currently possible to apply multiple hover\n", " | labels to points on different axes.\n", " | \n", " | Note: `hover` can only be called with multiple dicts if\n", " | 'curveNumber' and 'pointNumber' are the keys of the dicts\n", " | \n", " | Examples:\n", " | Initialization - Start each example below with this setup:\n", " | ```\n", " | from plotly.widgets import Graph\n", " | from IPython.display import display\n", " | \n", " | graph = GraphWidget('https://plot.ly/~chris/3979')\n", " | display(graph)\n", " | ```\n", " | \n", " | Example 1 - Apply a label to the (x, y) point (3, 2)\n", " | ```\n", " | graph.hover({'xval': 3, 'yval': 2, 'hovermode': 'closest'})\n", " | ```\n", " | \n", " | Example 2 -Apply a labels to all the points with the x coordinate 3\n", " | ```\n", " | graph.hover({'xval': 3, 'hovermode': 'x'})\n", " | ```\n", " | \n", " | Example 3 - Apply a label to the first point of the first trace\n", " | and the second point of the second trace.\n", " | ```\n", " | graph.hover({'curveNumber': 0, 'pointNumber': 0},\n", " | {'curveNumber': 1, 'pointNumber': 1})\n", " | ```\n", " | \n", " | on_click(self, callback, remove=False)\n", " | Assign a callback to click events propagated\n", " | by clicking on point(s) in the Plotly graph.\n", " | \n", " | Args:\n", " | callback (function): Callback function this is called\n", " | on click events with the signature:\n", " | callback(widget, hover_obj) -> None\n", " | \n", " | Args:\n", " | widget (GraphWidget): The current instance\n", " | of the graph widget that this callback is assigned to.\n", " | \n", " | click_obj (dict): a nested dict that describes\n", " | which point(s) were clicked on.\n", " | \n", " | click_obj example:\n", " | [\n", " | {\n", " | 'curveNumber': 1,\n", " | 'pointNumber': 2,\n", " | 'x': 4,\n", " | 'y': 14\n", " | }\n", " | ]\n", " | \n", " | remove (bool, optional): If False, attach the callback.\n", " | If True, remove the callback. Defaults to False.\n", " | \n", " | \n", " | Returns:\n", " | None\n", " | \n", " | Example:\n", " | ```\n", " | from IPython.display import display\n", " | def message_handler(widget, msg):\n", " | display(widget._graph_url)\n", " | display(msg)\n", " | \n", " | g = GraphWidget('https://plot.ly/~chris/3375')\n", " | display(g)\n", " | \n", " | g.on_click(message_handler)\n", " | ```\n", " | \n", " | on_hover(self, callback, remove=False)\n", " | Assign a callback to hover events propagated\n", " | by hovering over points in the Plotly graph.\n", " | \n", " | Args:\n", " | callback (function): Callback function this is called\n", " | on hover events with the signature:\n", " | callback(widget, hover_obj) -> None\n", " | \n", " | Args:\n", " | widget (GraphWidget): The current instance\n", " | of the graph widget that this callback is assigned to.\n", " | \n", " | hover_obj (dict): a nested dict that describes\n", " | which point(s) was hovered over.\n", " | \n", " | hover_obj example:\n", " | [\n", " | {\n", " | 'curveNumber': 1,\n", " | 'pointNumber': 2,\n", " | 'x': 4,\n", " | 'y': 14\n", " | }\n", " | ]\n", " | \n", " | remove (bool, optional): If False, attach the callback.\n", " | If True, remove the callback. Defaults to False.\n", " | \n", " | \n", " | Returns:\n", " | None\n", " | \n", " | Example:\n", " | ```\n", " | from IPython.display import display\n", " | def message_handler(widget, hover_msg):\n", " | display(widget._graph_url)\n", " | display(hover_msg)\n", " | \n", " | g = GraphWidget('https://plot.ly/~chris/3375')\n", " | display(g)\n", " | \n", " | g.on_hover(message_handler)\n", " | ```\n", " | \n", " | on_zoom(self, callback, remove=False)\n", " | Assign a callback to zoom events propagated\n", " | by zooming in regions in the Plotly graph.\n", " | \n", " | Args:\n", " | callback (function): Callback function this is called\n", " | on zoom events with the signature:\n", " | callback(widget, ranges) -> None\n", " | \n", " | Args:\n", " | widget (GraphWidget): The current instance\n", " | of the graph widget that this callback is assigned to.\n", " | \n", " | ranges (dict): A description of the\n", " | region that was zoomed into.\n", " | \n", " | ranges example:\n", " | {\n", " | 'x': [1.8399058038561549, 2.16443359662],\n", " | 'y': [4.640902872777017, 7.855677154582]\n", " | }\n", " | \n", " | remove (bool, optional): If False, attach the callback.\n", " | If True, remove the callback. Defaults to False.\n", " | \n", " | Returns:\n", " | None\n", " | \n", " | Example:\n", " | ```\n", " | from IPython.display import display\n", " | def message_handler(widget, ranges):\n", " | display(widget._graph_url)\n", " | display(ranges)\n", " | \n", " | g = GraphWidget('https://plot.ly/~chris/3375')\n", " | display(g)\n", " | \n", " | g.on_zoom(message_handler)\n", " | ```\n", " | \n", " | relayout(self, layout)\n", " | Update the layout of the Plotly graph.\n", " | \n", " | Args:\n", " | layout (dict):\n", " | dict where keys are the graph attribute strings\n", " | and values are the value of the graph attribute.\n", " | \n", " | To update graph objects that are nested, like\n", " | the title of an axis, combine the keys with a period\n", " | e.g. `xaxis.title`. To set a value of an element in an array,\n", " | like an axis's range, use brackets, e.g. 'xaxis.range[0]'.\n", " | To replace an entire nested object, just specify the value to\n", " | the sub-object. See example 4 below.\n", " | \n", " | See all of the layout attributes in our reference documentation\n", " | https://plot.ly/python/reference/#Layout\n", " | Or by calling `help` on `plotly.graph_objs.Layout`\n", " | \n", " | Examples - Start each example below with this setup:\n", " | Initialization:\n", " | ```\n", " | from plotly.widgets import Graph\n", " | from IPython.display import display\n", " | \n", " | graph = GraphWidget('https://plot.ly/~chris/3979')\n", " | display(graph)\n", " | ```\n", " | \n", " | Example 1 - Update the title\n", " | ```\n", " | graph.relayout({'title': 'Experimental results'})\n", " | ```\n", " | \n", " | Example 2 - Update the xaxis range\n", " | ```\n", " | graph.relayout({'xaxis.range': [-1, 6]})\n", " | ```\n", " | \n", " | Example 3 - Update the first element of the xaxis range\n", " | ```\n", " | graph.relayout({'xaxis.range[0]': -3})\n", " | ```\n", " | \n", " | Example 4 - Replace the entire xaxis object\n", " | ```\n", " | graph.relayout({'xaxis': {'title': 'Experimental results'}})\n", " | ```\n", " | \n", " | reorder_traces(self, current_indices, new_indices=None)\n", " | Reorder the traces in a graph.\n", " | \n", " | The order of the traces determines the order of the legend entries\n", " | and the layering of the objects drawn in the graph, i.e. the first\n", " | trace is drawn first and the second trace is drawn on top of the\n", " | first trace.\n", " | \n", " | Args:\n", " | current_indices (list[int]): The index of the traces to reorder.\n", " | \n", " | new_indices (list[int], optional): The index of the traces\n", " | specified by `current_indices` after ordering.\n", " | If None, then move the traces to the end.\n", " | \n", " | Examples:\n", " | Example 1 - Move the first trace to the second to last\n", " | position, the second trace to the last position\n", " | ```\n", " | graph.move_traces([0, 1])\n", " | ```\n", " | \n", " | Example 2 - Move the first trace to the second position,\n", " | the second trace to the first position.\n", " | ```\n", " | graph.move_traces([0], [1])\n", " | ```\n", " | \n", " | restyle(self, data, indices=None)\n", " | Update the style of existing traces in the Plotly graph.\n", " | \n", " | Args:\n", " | update (dict):\n", " | dict where keys are the graph attribute strings\n", " | and values are the value of the graph attribute.\n", " | \n", " | To update graph objects that are nested, like\n", " | a marker's color, combine the keys with a period,\n", " | e.g. `marker.color`. To replace an entire nested object,\n", " | like `marker`, set the value to the object.\n", " | See Example 2 below.\n", " | \n", " | To update an attribute of multiple traces, set the\n", " | value to an list of values. If the list is shorter\n", " | than the number of traces, the values will wrap around.\n", " | Note: this means that for values that are naturally an array,\n", " | like `x` or `colorscale`, you need to wrap the value\n", " | in an extra array,\n", " | i.e. {'colorscale': [[[0, 'red'], [1, 'green']]]}\n", " | \n", " | You can also supply values to different traces with the\n", " | indices argument.\n", " | \n", " | See all of the graph attributes in our reference documentation\n", " | here: https://plot.ly/python/reference or by calling `help` on\n", " | graph objects in `plotly.graph_objs`.\n", " | \n", " | indices (list, optional):\n", " | Specify which traces to apply the update dict to.\n", " | Negative indices are supported.\n", " | If indices are not given, the update will apply to\n", " | *all* traces.\n", " | \n", " | Examples:\n", " | Initialization - Start each example below with this setup:\n", " | ```\n", " | from plotly.widgets import Graph\n", " | from IPython.display import display\n", " | \n", " | graph = GraphWidget('https://plot.ly/~chris/3979')\n", " | display(graph)\n", " | ```\n", " | \n", " | Example 1 - Set `marker.color` to red in every trace in the graph\n", " | ```\n", " | graph.restyle({'marker.color': 'red'})\n", " | ```\n", " | \n", " | Example 2 - Replace `marker` with {'color': 'red'}\n", " | ```\n", " | graph.restyle({'marker': {'color': red'}})\n", " | ```\n", " | \n", " | Example 3 - Set `marker.color` to red\n", " | in the first trace of the graph\n", " | ```\n", " | graph.restyle({'marker.color': 'red'}, indices=[0])\n", " | ```\n", " | \n", " | Example 4 - Set `marker.color` of all of the traces to\n", " | alternating sequences of red and green\n", " | ```\n", " | graph.restyle({'marker.color': ['red', 'green']})\n", " | ```\n", " | \n", " | Example 5 - Set just `marker.color` of the first two traces\n", " | to red and green\n", " | ```\n", " | graph.restyle({'marker.color': ['red', 'green']}, indices=[0, 1])\n", " | ```\n", " | \n", " | Example 6 - Set multiple attributes of all of the traces\n", " | ```\n", " | graph.restyle({\n", " | 'marker.color': 'red',\n", " | 'line.color': 'green'\n", " | })\n", " | ```\n", " | \n", " | Example 7 - Update the data of the first trace\n", " | ```\n", " | graph.restyle({\n", " | 'x': [[1, 2, 3]],\n", " | 'y': [[10, 20, 30]],\n", " | }, indices=[0])\n", " | ```\n", " | \n", " | Example 8 - Update the data of the first two traces\n", " | ```\n", " | graph.restyle({\n", " | 'x': [[1, 2, 3],\n", " | [1, 2, 4]],\n", " | 'y': [[10, 20, 30],\n", " | [5, 8, 14]],\n", " | }, indices=[0, 1])\n", " | ```\n", " | \n", " | ----------------------------------------------------------------------\n", " | Methods inherited from IPython.html.widgets.widget.DOMWidget:\n", " | \n", " | add_class(self, class_names, selector='')\n", " | Add class[es] to a DOM element.\n", " | \n", " | Parameters\n", " | ----------\n", " | class_names: unicode or list\n", " | Class name(s) to add to the DOM element(s).\n", " | selector: unicode (optional)\n", " | JQuery selector to select the DOM element(s) that the class(es) will\n", " | be added to.\n", " | \n", " | get_css(self, key, selector='')\n", " | Get a CSS property of the widget.\n", " | \n", " | Note: This function does not actually request the CSS from the \n", " | front-end; Only properties that have been set with set_css can be read.\n", " | \n", " | Parameters\n", " | ----------\n", " | key: unicode\n", " | CSS key\n", " | selector: unicode (optional)\n", " | JQuery selector used when the CSS key/value was set.\n", " | \n", " | remove_class(self, class_names, selector='')\n", " | Remove class[es] from a DOM element.\n", " | \n", " | Parameters\n", " | ----------\n", " | class_names: unicode or list\n", " | Class name(s) to remove from the DOM element(s).\n", " | selector: unicode (optional)\n", " | JQuery selector to select the DOM element(s) that the class(es) will\n", " | be removed from.\n", " | \n", " | set_css(self, dict_or_key, value=None, selector='')\n", " | Set one or more CSS properties of the widget.\n", " | \n", " | This function has two signatures:\n", " | - set_css(css_dict, selector='')\n", " | - set_css(key, value, selector='')\n", " | \n", " | Parameters\n", " | ----------\n", " | css_dict : dict\n", " | CSS key/value pairs to apply\n", " | key: unicode\n", " | CSS key\n", " | value:\n", " | CSS value\n", " | selector: unicode (optional, kwarg only)\n", " | JQuery selector to use to apply the CSS key/value. If no selector \n", " | is provided, an empty selector is used. An empty selector makes the \n", " | front-end try to apply the css to a default element. The default\n", " | element is an attribute unique to each view, which is a DOM element\n", " | of the view that should be styled with common CSS (see \n", " | `$el_to_style` in the Javascript code).\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data descriptors inherited from IPython.html.widgets.widget.DOMWidget:\n", " | \n", " | visible\n", " | A boolean (True, False) trait.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Methods inherited from IPython.html.widgets.widget.Widget:\n", " | \n", " | __del__(self)\n", " | Object disposal\n", " | \n", " | close(self)\n", " | Close method.\n", " | \n", " | Closes the widget which closes the underlying comm.\n", " | When the comm is closed, all of the widget views are automatically\n", " | removed from the front-end.\n", " | \n", " | get_state(self, key=None)\n", " | Gets the widget state, or a piece of it.\n", " | \n", " | Parameters\n", " | ----------\n", " | key : unicode (optional)\n", " | A single property's name to get.\n", " | \n", " | on_displayed(self, callback, remove=False)\n", " | (Un)Register a widget displayed callback.\n", " | \n", " | Parameters\n", " | ----------\n", " | callback: method handler\n", " | Must have a signature of::\n", " | \n", " | callback(widget, **kwargs)\n", " | \n", " | kwargs from display are passed through without modification.\n", " | remove: bool\n", " | True if the callback should be unregistered.\n", " | \n", " | on_msg(self, callback, remove=False)\n", " | (Un)Register a custom msg receive callback.\n", " | \n", " | Parameters\n", " | ----------\n", " | callback: callable\n", " | callback will be passed two arguments when a message arrives::\n", " | \n", " | callback(widget, content)\n", " | \n", " | remove: bool\n", " | True if the callback should be unregistered.\n", " | \n", " | send(self, content)\n", " | Sends a custom msg to the widget model in the front-end.\n", " | \n", " | Parameters\n", " | ----------\n", " | content : dict\n", " | Content of the message to send.\n", " | \n", " | send_state(self, key=None)\n", " | Sends the widget state, or a piece of it, to the front-end.\n", " | \n", " | Parameters\n", " | ----------\n", " | key : unicode (optional)\n", " | A single property's name to sync with the front-end.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Static methods inherited from IPython.html.widgets.widget.Widget:\n", " | \n", " | on_widget_constructed(callback)\n", " | Registers a callback to be called when a widget is constructed.\n", " | \n", " | The callback must have the following signature:\n", " | callback(widget)\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data descriptors inherited from IPython.html.widgets.widget.Widget:\n", " | \n", " | comm\n", " | Gets the Comm associated with this widget.\n", " | \n", " | If a Comm doesn't exist yet, a Comm will be created automagically.\n", " | \n", " | keys\n", " | An instance of a Python list.\n", " | \n", " | model_id\n", " | Gets the model id of this widget.\n", " | \n", " | If a Comm doesn't exist yet, a Comm will be created automagically.\n", " | \n", " | msg_throttle\n", " | An int trait.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data and other attributes inherited from IPython.html.widgets.widget.Widget:\n", " | \n", " | widgets = {}\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data descriptors inherited from IPython.config.configurable.LoggingConfigurable:\n", " | \n", " | log\n", " | A trait whose value must be an instance of a specified class.\n", " | \n", " | The value can also be an instance of a subclass of the specified class.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Methods inherited from IPython.config.configurable.Configurable:\n", " | \n", " | update_config(self, config)\n", " | Fire the traits events when the config is updated.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Class methods inherited from IPython.config.configurable.Configurable:\n", " | \n", " | class_config_section(cls) from IPython.utils.traitlets.MetaHasTraits\n", " | Get the config class config section\n", " | \n", " | class_get_help(cls, inst=None) from IPython.utils.traitlets.MetaHasTraits\n", " | Get the help string for this class in ReST format.\n", " | \n", " | If `inst` is given, it's current trait values will be used in place of\n", " | class defaults.\n", " | \n", " | class_get_trait_help(cls, trait, inst=None) from IPython.utils.traitlets.MetaHasTraits\n", " | Get the help string for a single trait.\n", " | \n", " | If `inst` is given, it's current trait values will be used in place of\n", " | the class default.\n", " | \n", " | class_print_help(cls, inst=None) from IPython.utils.traitlets.MetaHasTraits\n", " | Get the help string for a single trait and print it.\n", " | \n", " | section_names(cls) from IPython.utils.traitlets.MetaHasTraits\n", " | return section names as a list\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data descriptors inherited from IPython.config.configurable.Configurable:\n", " | \n", " | config\n", " | A trait whose value must be an instance of a specified class.\n", " | \n", " | The value can also be an instance of a subclass of the specified class.\n", " | \n", " | parent\n", " | A trait whose value must be an instance of a specified class.\n", " | \n", " | The value can also be an instance of a subclass of the specified class.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Methods inherited from IPython.utils.traitlets.HasTraits:\n", " | \n", " | on_trait_change(self, handler, name=None, remove=False)\n", " | Setup a handler to be called when a trait changes.\n", " | \n", " | This is used to setup dynamic notifications of trait changes.\n", " | \n", " | Static handlers can be created by creating methods on a HasTraits\n", " | subclass with the naming convention '_[traitname]_changed'. Thus,\n", " | to create static handler for the trait 'a', create the method\n", " | _a_changed(self, name, old, new) (fewer arguments can be used, see\n", " | below).\n", " | \n", " | Parameters\n", " | ----------\n", " | handler : callable\n", " | A callable that is called when a trait changes. Its\n", " | signature can be handler(), handler(name), handler(name, new)\n", " | or handler(name, old, new).\n", " | name : list, str, None\n", " | If None, the handler will apply to all traits. If a list\n", " | of str, handler will apply to all names in the list. If a\n", " | str, the handler will apply just to that name.\n", " | remove : bool\n", " | If False (the default), then install the handler. If True\n", " | then unintall it.\n", " | \n", " | trait_metadata(self, traitname, key)\n", " | Get metadata values for trait by key.\n", " | \n", " | trait_names(self, **metadata)\n", " | Get a list of all the names of this class' traits.\n", " | \n", " | traits(self, **metadata)\n", " | Get a `dict` of all the traits of this class. The dictionary\n", " | is keyed on the name and the values are the TraitType objects.\n", " | \n", " | The TraitTypes returned don't know anything about the values\n", " | that the various HasTrait's instances are holding.\n", " | \n", " | The metadata kwargs allow functions to be passed in which\n", " | filter traits based on metadata values. The functions should\n", " | take a single value as an argument and return a boolean. If\n", " | any function returns False, then the trait is not included in\n", " | the output. This does not allow for any simple way of\n", " | testing that a metadata name exists and has any\n", " | value because get_metadata returns None if a metadata key\n", " | doesn't exist.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Class methods inherited from IPython.utils.traitlets.HasTraits:\n", " | \n", " | class_trait_names(cls, **metadata) from IPython.utils.traitlets.MetaHasTraits\n", " | Get a list of all the names of this class' traits.\n", " | \n", " | This method is just like the :meth:`trait_names` method,\n", " | but is unbound.\n", " | \n", " | class_traits(cls, **metadata) from IPython.utils.traitlets.MetaHasTraits\n", " | Get a `dict` of all the traits of this class. The dictionary\n", " | is keyed on the name and the values are the TraitType objects.\n", " | \n", " | This method is just like the :meth:`traits` method, but is unbound.\n", " | \n", " | The TraitTypes returned don't know anything about the values\n", " | that the various HasTrait's instances are holding.\n", " | \n", " | The metadata kwargs allow functions to be passed in which\n", " | filter traits based on metadata values. The functions should\n", " | take a single value as an argument and return a boolean. If\n", " | any function returns False, then the trait is not included in\n", " | the output. This does not allow for any simple way of\n", " | testing that a metadata name exists and has any\n", " | value because get_metadata returns None if a metadata key\n", " | doesn't exist.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Static methods inherited from IPython.utils.traitlets.HasTraits:\n", " | \n", " | __new__(cls, *args, **kw)\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data descriptors inherited from IPython.utils.traitlets._NewBase:\n", " | \n", " | __dict__\n", " | dictionary for instance variables (if defined)\n", " | \n", " | __weakref__\n", " | list of weak references to the object (if defined)\n", "\n" ] } ], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Initialize a Graph widget with a Plotly URL" ] }, { "cell_type": "code", "collapsed": false, "input": [ "url = py.plot([Scatter(x=[1, 2, 3], y=[4, 6, 9]), Scatter(x=[1, 2, 3], y=[10, 30, 20])], filename='widget template', auto_open=False)\n", "print url" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "https://plot.ly/~chris/4099\n" ] } ], "prompt_number": 5 }, { "cell_type": "code", "collapsed": false, "input": [ "graph = GraphWidget(url)\n", "g = graph\n", "graph" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "https://plot.ly/~chris/4099\n" ] }, { "metadata": {}, "output_type": "display_data", "text": [ "{'x': [0.8075015499070055, 4.1924984500929945],\n", " 'y': [3.1361149110807114, 31.86388508891929]}" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Update the Plotly graph. This is done entirely on the client" ] }, { "cell_type": "code", "collapsed": false, "input": [ "help(graph.restyle)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Help on method restyle in module plotly.widgets.graph_widget:\n", "\n", "restyle(self, data, indices=None) method of plotly.widgets.graph_widget.GraphWidget instance\n", " Update the style of existing traces in the Plotly graph.\n", " \n", " Args:\n", " update (dict):\n", " dict where keys are the graph attribute strings\n", " and values are the value of the graph attribute.\n", " \n", " To update graph objects that are nested, like\n", " a marker's color, combine the keys with a period,\n", " e.g. `marker.color`. To replace an entire nested object,\n", " like `marker`, set the value to the object.\n", " See Example 2 below.\n", " \n", " To update an attribute of multiple traces, set the\n", " value to an list of values. If the list is shorter\n", " than the number of traces, the values will wrap around.\n", " Note: this means that for values that are naturally an array,\n", " like `x` or `colorscale`, you need to wrap the value\n", " in an extra array,\n", " i.e. {'colorscale': [[[0, 'red'], [1, 'green']]]}\n", " \n", " You can also supply values to different traces with the\n", " indices argument.\n", " \n", " See all of the graph attributes in our reference documentation\n", " here: https://plot.ly/python/reference or by calling `help` on\n", " graph objects in `plotly.graph_objs`.\n", " \n", " indices (list, optional):\n", " Specify which traces to apply the update dict to.\n", " Negative indices are supported.\n", " If indices are not given, the update will apply to\n", " *all* traces.\n", " \n", " Examples:\n", " Initialization - Start each example below with this setup:\n", " ```\n", " from plotly.widgets import Graph\n", " from IPython.display import display\n", " \n", " graph = GraphWidget('https://plot.ly/~chris/3979')\n", " display(graph)\n", " ```\n", " \n", " Example 1 - Set `marker.color` to red in every trace in the graph\n", " ```\n", " graph.restyle({'marker.color': 'red'})\n", " ```\n", " \n", " Example 2 - Replace `marker` with {'color': 'red'}\n", " ```\n", " graph.restyle({'marker': {'color': red'}})\n", " ```\n", " \n", " Example 3 - Set `marker.color` to red\n", " in the first trace of the graph\n", " ```\n", " graph.restyle({'marker.color': 'red'}, indices=[0])\n", " ```\n", " \n", " Example 4 - Set `marker.color` of all of the traces to\n", " alternating sequences of red and green\n", " ```\n", " graph.restyle({'marker.color': ['red', 'green']})\n", " ```\n", " \n", " Example 5 - Set just `marker.color` of the first two traces\n", " to red and green\n", " ```\n", " graph.restyle({'marker.color': ['red', 'green']}, indices=[0, 1])\n", " ```\n", " \n", " Example 6 - Set multiple attributes of all of the traces\n", " ```\n", " graph.restyle({\n", " 'marker.color': 'red',\n", " 'line.color': 'green'\n", " })\n", " ```\n", " \n", " Example 7 - Update the data of the first trace\n", " ```\n", " graph.restyle({\n", " 'x': [[1, 2, 3]],\n", " 'y': [[10, 20, 30]],\n", " }, indices=[0])\n", " ```\n", " \n", " Example 8 - Update the data of the first two traces\n", " ```\n", " graph.restyle({\n", " 'x': [[1, 2, 3],\n", " [1, 2, 4]],\n", " 'y': [[10, 20, 30],\n", " [5, 8, 14]],\n", " }, indices=[0, 1])\n", " ```\n", "\n" ] } ], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "graph.restyle({'name': ['control', 'experiment']})" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 8 }, { "cell_type": "code", "collapsed": false, "input": [ "graph.relayout({'xaxis.title': 'samples'})" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [ "graph.add_traces(Scatter(x=[1,2,3], y=[5, 4, 5], name='another sample'))" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Update the graph's data\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "g.restyle({'x': [[1,2,3], \n", " [1, 2, 4]],\n", " 'y': [[10,20,35],\n", " [5, 8, 14]]\n", "}, indices=[0, 1])" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Assign handlers to 'click', 'hover', and 'zoom' events" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.display import display, clear_output\n", "def message_handler(widget, msg):\n", " clear_output()\n", " print widget._graph_url\n", " display(msg)\n", "\n", "g.on_click(message_handler)\n", "g.on_hover(message_handler)\n", "g.on_zoom(message_handler)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 12 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Manual hover over points" ] }, { "cell_type": "code", "collapsed": false, "input": [ "g.hover({'xval': 2, 'yval': 8})" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 13 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Here is a sequence of graph edits" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.display import Image\n", "Image(url='http://i.imgur.com/69wyqjV.gif')" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "" ], "metadata": {}, "output_type": "pyout", "prompt_number": 14, "text": [ "" ] } ], "prompt_number": 14 }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.html import widgets # Widget definitions\n", "import json\n", "import time\n", "\n", "def info_popup(info):\n", " popup = widgets.PopupWidget(\n", " description='Scroll up to see the embedded plotly graph update',\n", " children=[widgets.HTMLWidget(value=json.dumps(info,indent=4).replace('\\n', '
').replace(' ', ' '))]\n", " )\n", " popup.set_css('display', 'none', selector='.btn')\n", " return popup\n", "\n", "style_sequence = [\n", " # Clear graph\n", " {\n", " 'data': {\n", " 'x': [],\n", " 'y': [],\n", " 'marker.color': '',\n", " 'marker.size': '',\n", " 'marker.symbol': '',\n", " 'line.color': '',\n", " 'line.width': '',\n", " 'name': ''\n", " },\n", " 'layout': {\n", " 'title': '',\n", " 'showlegend': False,\n", " 'legend.x': '',\n", " 'legend.y': '',\n", " 'legend.bgcolor': ''\n", " },\n", " 'hover': {}\n", " },\n", " # Add data\n", " {\n", " 'data': {\n", " 'x': [[1,2,3], \n", " [1, 2, 4]], \n", " 'y': [[10,20,30],\n", " [5, 8, 14]]\n", " },\n", " 'traces': [0, 1]\n", " },\n", " # Restyle markers\n", " {\n", " 'data': {\n", " 'marker.color': ['rgb(0, 67, 88)', 'rgb(31, 138, 112)'],\n", " 'marker.size': 10,\n", " 'marker.symbol': 'hexagon-open'\n", " },\n", " 'traces': [0, 1]\n", " },\n", " # Restyle lines\n", " {\n", " 'data': {\n", " 'line.color': ['rgb(0, 67, 88)', 'rgb(31, 138, 112)'],\n", " 'line.width': 3\n", " }\n", " },\n", " # Add title\n", " {\n", " 'layout': {\n", " 'title': 'Trials',\n", " }\n", " },\n", " # Add legend\n", " {\n", " 'layout': {\n", " 'showlegend': True,\n", " }\n", " },\n", " # Add legend names\n", " {\n", " 'data': {\n", " 'name': ['Control', 'Experiment']\n", " },\n", " 'traces': [0, 1]\n", " },\n", " # Move legend\n", " {\n", " 'layout': {\n", " 'legend.x': 0.02,\n", " 'legend.y': 1,\n", " 'legend.bgcolor': 'rgba(255, 255, 255, 0.5)'\n", " }\n", " },\n", " {'hover': {'xval': 2, 'yval': 8}},\n", " {'hover': {'xval': 2, 'yval': 8, 'hovermode': 'closest'}},\n", " {'xval': 2, 'yval': 8, 'hovermode': 'x'},\n", " {'hover': [{'curveNumber': 0, 'pointNumber': 0}]},\n", " {'hover': [{'curveNumber': 0, 'pointNumber': 0},\n", " {'curveNumber': 0, 'pointNumber': 1}]},\n", " {'hover': [{'curveNumber': 0, 'pointNumber': 2},\n", " {'curveNumber': 1, 'pointNumber': 1}]},\n", " {'hover': [{'curveNumber': 0, 'xval': 1, 'yval': 10},\n", " {'curveNumber': 0, 'xval': 2, 'yval': 20},\n", " {'curveNumber': 0, 'xval': 3, 'yval': 30},\n", " {'curveNumber': 1, 'xval': 1, 'yval': 5},\n", " {'curveNumber': 1, 'xval': 2, 'yval': 8},\n", " {'curveNumber': 1, 'xval': 4, 'yval': 14}\n", " ]}\n", "]\n", "\n", "for s in style_sequence:\n", " popup = info_popup(s)\n", " # display(popup)\n", " if 'data' in s:\n", " if 'traces' in s:\n", " g.restyle(s['data'], indices=s['traces'])\n", " else:\n", " g.restyle(s['data'])\n", " if 'layout' in s:\n", " g.relayout(s['layout'])\n", " if 'hover' in s:\n", " g.hover(s['hover'])\n", " time.sleep(3)\n", "\n", " popup.close()\n", " clear_output()" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 15 }, { "cell_type": "code", "collapsed": false, "input": [ "# CSS styling within IPython notebook - feel free to re-use\n", "from IPython.core.display import HTML\n", "import urllib2\n", "\n", "HTML(urllib2.urlopen('http://bit.ly/1Bf5Hft').read())" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "" ], "metadata": {}, "output_type": "pyout", "prompt_number": 4, "text": [ "" ] } ], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }